home *** CD-ROM | disk | FTP | other *** search
/ Utilities Professional 1-1500 / Utilities Professional 1-1500 (1994)(WPD)[!].iso / 12511500 / var1411.dms / var1411.adf / Source / CacheClock1.1.s < prev    next >
Text File  |  1994-02-02  |  39KB  |  2,056 lines

  1.  
  2. ;Comment out next line to make non-detatching program
  3. DETATCH        EQU    0
  4.  
  5. DefaultBuffers    EQU    256        number of sectors to remember
  6. WindowSmallX    EQU    $171        Small window sizes
  7. WindowSmallY    EQU    $a
  8. WindowBigX    EQU    $1a8        Big window sizes
  9. WindowBigY    EQU    $6a
  10.  
  11. MoreGadget    EQU    $100        Gadget id numbers
  12. FewerGadget    EQU    $101
  13.  
  14.     rsreset                structure of a remembered sector
  15. NextHash    rs.l    1        hash table links
  16. PrevHash    rs.l    1
  17. NextInList    rs.l    1        links for deallocation of sectors
  18. PrevInList    rs.l    1
  19. SectorOffset    rs.l    1        disk offset of sector in bytes
  20. WhichDrive    rs.w    1        drive number of sector
  21. Sector        rs.b    $200        sectors data
  22. SectorSize    rs.w    0
  23.  
  24.     include    "df0:Source/CacheClock.i"
  25.  
  26. Start    movem.l    d0/a0,-(sp)        save CLI line for later
  27.     move.l    $4.w,a6            Open dos library
  28.     lea    DosName(pc),a1
  29.     jsr    OpenLibrary(a6)
  30.     move.l    d0,DosBase        save base address
  31.     beq    NoDos
  32.  
  33.     sub.l    a1,a1            Standard CLI/workbench startup
  34.     move.l    $4.w,a6
  35.     jsr    FindTask(a6)
  36.  
  37.     move.l    d0,a2
  38.     tst.l    pr_CLI(a2)
  39.     bne.s    CLIcall
  40.     lea    pr_MsgPort(a2),a0    Started from workbench
  41.     move.l    $4.w,a6
  42.     jsr    WaitPort(a6)        wait for workbench message
  43.  
  44.     lea    pr_MsgPort(a2),a0    get that message
  45.     move.l    $4.w,a6
  46.     jsr    GetMsg(a6)
  47.     move.l    d0,WorkbenchMsg        save it for later
  48.  
  49.     movem.l    (sp)+,d0/a0        ignore registers
  50.     bra.s    StartJoin
  51.  
  52. CLIcall    movem.l    (sp)+,d0/a3
  53.     clr.b    -1(a3,d0.l)        Null terminate command line
  54.     bsr    ParseCLI        CLI call, so parse command line
  55.     beq.s    NoDos            Bad CLI command ?
  56.  
  57. StartJoin
  58.     IFD    DETATCH
  59. ;detatch main part of program from CLI
  60.     lea    Start-4(pc),a0        a0 is ptr to next segment in list
  61.     move.l    (a0),d3            d3 = BPTR to next hunk
  62.     clr.l    (a0)            unlink second hunk so that it is
  63. ;                    not de-allocated when this terminates
  64.  
  65.     move.l    #ProcessName,d1
  66.     moveq    #0,d2            priority of 0
  67.     move.l    #4000,d4        4000 byte stack
  68.     move.l    DosBase,a6
  69.     jsr    CreateProc(a6)        create process
  70.     ENDC
  71.  
  72.     IFND    DETATCH            code for non-detatching program
  73.     bsr    _main
  74.     ENDC
  75.  
  76.     move.l    WorkbenchMsg(pc),d0
  77.     beq.s    NoDos
  78.     move.l    $4.w,a6        Stop other tasks from interrupting when
  79.     jsr    Forbid(a6)    closing down otherwise workbench crashes
  80.  
  81.     move.l    WorkbenchMsg(pc),a1    Workbench open, so signal task ended
  82.     jsr    ReplyMsg(a6)
  83.  
  84. NoDos    moveq    #0,d0
  85.     rts
  86.  
  87.  
  88. **************** Reads an ascii number from (a3)+ (CLI input)
  89. * GetCLInumber *
  90. **************** returns d0 = number
  91. GetCLInumber
  92.     moveq    #0,d0        default number = 0
  93. SkipSpaces
  94.     moveq    #0,d1
  95.     move.b    (a3),d1        skip spaces after command
  96.     cmp.b    #" ",d1
  97.     beq.s    SkipSpc
  98.     cmp.b    #"    ",d1
  99.     bne.s    StartNumber
  100. SkipSpc    addq.w    #1,a3
  101.     bra.s    SkipSpaces
  102.  
  103. StartNumber
  104.     move.b    (a3),d1        get next digit
  105.     sub.w    #"0",d1
  106.     bmi.s    EndNumber
  107.     cmp.w    #10,d1
  108.     bpl.s    EndNumber
  109.     add.l    d0,d0        multiply d0 by 10 & add d1 quickly 
  110.     add.l    d0,d1
  111.     add.l    d0,d0
  112.     add.l    d0,d0
  113.     add.l    d1,d0
  114.     addq.w    #1,a3
  115.     bra.s    StartNumber
  116. EndNumber
  117.     rts
  118.  
  119. ************    Execute given CLI commands (a3) = line to parse
  120. * ParseCLI *
  121. ************    returns d0=-1, CLI command ok, d0=0, bad CLI command
  122. ParseCLI
  123.     lea    MyWindow,a0        quick reference for altering structure
  124.  
  125. GetNextChr
  126.     move.b    (a3)+,d0        Parse CLI command
  127.     beq    EndOfCLI
  128.     cmp.b    #" ",d0            Ignore spaces
  129.     beq.s    GetNextChr
  130.     cmp.b    #"    ",d0
  131.     beq.s    GetNextChr
  132.     cmp.b    #"-",d0            check for switches
  133.     beq.s    DoSwitches
  134.     bra.s    BadCLI
  135.  
  136. DoSwitches
  137.     move.b    (a3)+,d0        Set switches
  138.     beq.s    EndOfCLI
  139.     cmp.b    #" ",d0
  140.     beq.s    GetNextChr
  141.     cmp.b    #"    ",d0
  142.     beq.s    GetNextChr
  143.     and.w    #$5f,d0            conversion from lower to upper case
  144.     cmp.w    #"B",d0
  145.     bne.s    NotOptB
  146.     bsr    GetCLInumber        -b(number of blocks)
  147.     move.l    d0,AddDefaultSectors+2
  148.     bra.s    DoSwitches
  149.  
  150. NotOptB    cmp.w    #"X",d0
  151.     bne.s    NotOptX
  152.     bsr    GetCLInumber        -x(x position of window)
  153.     move.w    d0,nw_LeftEdge(a0)
  154.     bra.s    DoSwitches
  155.  
  156. NotOptX    cmp.w    #"Y",d0
  157.     bne.s    NotOptY
  158.     bsr    GetCLInumber        -y(y position of window)
  159.     move.w    d0,nw_TopEdge(a0)
  160.     bra.s    DoSwitches
  161.  
  162. NotOptY    cmp.w    #"L",d0
  163.     bne.s    BadCLI
  164.     clr.b    GadgetSmall        -l (large window)
  165.  
  166.     move.w    #WindowBigX,nw_Width(a0)    Change window sizes
  167.     move.w    #WindowBigY,nw_Height(a0)
  168.     cmp.w    #220,nw_LeftEdge(a0)    if window x not changed, then move
  169.     bne.s    DoSwitches        back a bit, so that it will open
  170.     move.w    #216,nw_LeftEdge(a0)
  171.     bra.s    DoSwitches
  172.  
  173. EndOfCLI
  174.     moveq    #-1,d0            exit - CLI command OK
  175.     rts
  176.  
  177. BadCLI    move.l    $4.w,a6
  178.     move.l    DosBase,a6        Get CLI output file handle
  179.     jsr    Output(a6)
  180.  
  181.     move.l    d0,d1
  182.     move.l    #BadCLIMsg,d2        write message to CLI window
  183.     move.l    #BadEndMsg-BadCLIMsg,d3
  184.     jsr    Write(a6)
  185.  
  186.     move.l    a6,a1            close dos.library
  187.     move.l    $4.w,a6
  188.     jsr    CloseLibrary(a6)
  189.  
  190.     moveq    #0,d0            exit - error
  191.     rts
  192.  
  193.  
  194. WorkbenchMsg    dc.l    0        Workbench calling message
  195.  
  196. BadCLIMsg
  197.     dc.b    "CacheClock [-options]",10
  198.     dc.b    "    -b number    Default number of blocks",10
  199.     dc.b    "    -l        Large window",10
  200.     dc.b    "    -x number    Default X co-ordinate",10
  201.     dc.b    "    -y number    Default Y co-ordinate",10,10
  202.     dc.b    "E.g. CacheClock -b500 -lx200 -y10",10,10,0
  203. BadEndMsg
  204. DosName        dc.b    "dos.library",0
  205.     even                    word aling program counter
  206.  
  207.     IFD    DETATCH
  208. ;for detatching version, want main part in a separate hunk
  209.     SECTION    Program,CODE
  210.     ENDC
  211.  
  212. _main    move.l    a7,StartSP        Save start SP
  213.     lea    IntName(pc),a1
  214.     move.l    $4.w,a6
  215.     jsr    OpenLibrary(a6)
  216.     move.l    d0,IntBase
  217.     beq    NoInt
  218.  
  219.     lea    GfxName(pc),a1
  220.     jsr    OpenLibrary(a6)
  221.     move.l    d0,GfxBase
  222.     beq    NoGfx
  223.  
  224.     bsr    GetTrackdiskBase    Get trackdisk library
  225.     tst.l    d0
  226.     beq.s    Exit
  227.  
  228.     bsr    OpenProgramPort        check to see if already active
  229.     bne    Exit
  230.  
  231.     bsr    OpenMyWindow        Open window, & draw it if needed
  232.     beq.s    ExitPort
  233.  
  234.     jsr    OpenMyTimer
  235.     beq.s    ExitTimer
  236.  
  237.     bsr    AddDefaultSectors    Get 256 blocks
  238.     move.b    GadgetSmall(pc),d0
  239.     bne.s    NoBigWind
  240.     bsr    DrawBigWindow
  241. NoBigWind
  242.     bsr    RefreshStats        redraw window stats if big window
  243.  
  244.     bsr    PatchTrackdisk        Install trackdisk patch
  245.  
  246.  
  247. CheckGadgetsLoop
  248.     bsr    CheckGadgets
  249.     tst.l    d0            Close window pressed ?
  250.     bne.s    FreeAllSectors
  251.  
  252.     lea    TimerPort(pc),a0    Check for timer interrupt
  253.     move.l    $4.w,a6
  254.     jsr    GetMsg(a6)
  255.  
  256.     tst.l    d0
  257.     beq.s    NotTimerInt
  258.     bsr    SetTimer        reset timer for one second
  259. NotTimerInt
  260.     bsr    RefreshStats
  261.     move.l    Signals(pc),d0
  262.     move.l    $4.w,a6
  263.     jsr    Wait(a6)
  264.     bra.s    CheckGadgetsLoop
  265.  
  266.  
  267. FreeAllSectors
  268.     bsr    FreeSector        Free memory used by program
  269.     tst.l    d0
  270.     bne.s    FreeAllSectors
  271.  
  272.     bsr    CloseMyTimer
  273. ExitTimer
  274.     bsr    CloseMyWindow
  275. ExitPort
  276.     bsr    CloseProgramPort
  277.     bsr    RestoreTrackdisk
  278.  
  279.  
  280.  
  281. Exit    move.l    GfxBase(pc),a1        Close used libraries
  282.     move.l    $4.w,a6
  283.     jsr    CloseLibrary(a6)
  284.  
  285. NoGfx    move.l    IntBase(pc),a1
  286.     move.l    $4.w,a6
  287.     jsr    CloseLibrary(a6)
  288.  
  289. NoInt    move.l    StartSP(pc),a7
  290.  
  291. ;for detatching version, free memory used by second part of program, and
  292. ;then do a rts. This can be done easily by Jumping to a UnloadSeg call
  293. ;We cannot JSR to UnLoadSeg, then rts, since this code area will not be
  294. ;allocated, and a crash may occur.
  295.     IFD    DETATCH
  296.     move.l    #_main-4,d1        make BPTR to first section
  297.     lsr.l    #2,d1
  298.     move.l    DosBase(pc),a6
  299.     jmp    UnLoadSeg(a6)        free memory used by detached process
  300.     ENDC
  301.  
  302. ;for non-detaching version, just do a rts
  303.     IFND    DETATCH
  304.     rts
  305.     ENDC
  306.  
  307. *******************    Opens program port, & checks to see if program
  308. * OpenProgramPort *    is already active (quits if so)
  309. *******************    returns d0=0 port opened ok
  310. OpenProgramPort
  311.     move.l    $4.w,a6
  312.     jsr    Forbid(a6)
  313.  
  314.     lea    PortName(pc),a1
  315.     jsr    FindPort(a6)
  316.  
  317.     move.l    d0,d4
  318.     bne.s    AlreadyActive
  319.  
  320.     lea    ProgramPort(pc),a2
  321.     bsr    InitPort
  322.     tst.l    d0
  323.     beq.s    AlreadyActive
  324.  
  325.     move.l    #PortName,LN_NAME(a2)
  326.     move.l    a2,a1
  327.     move.l    $4.w,a6
  328.     jsr    AddPort(a6)
  329.     moveq    #0,d4
  330.  
  331. AlreadyActive
  332.     jsr    Permit(a6)
  333.     move.l    d4,d0
  334.     rts
  335.  
  336.  
  337. ********************    Closes the main programs port & frees it's signal
  338. * CloseProgramPort *
  339. ********************
  340. CloseProgramPort
  341.     move.l    $4.w,a6
  342.     jsr    Forbid(a6)
  343.  
  344.     lea    ProgramPort(pc),a1    Remove port
  345.     jsr    RemPort(a6)
  346.  
  347.     moveq    #0,d0            free signal bit used by port
  348.     move.b    MP_SIGBIT(a1),d0
  349.     lea    ProgramPort(pc),a1
  350.     jsr    FreeSignal(a6)
  351.     jmp    Permit(a6)
  352.  
  353. ProcessName    dc.b    "CacheClock",0
  354. ScreenName    dc.b    "CacheClock Disk accelerator and Clock",0
  355. TitleName    dc.b    "CacheClock V1.1 © 1993 Justin Leck",0
  356. GfxName        dc.b    "graphics.library",0
  357. IntName        dc.b    "intuition.library",0
  358.  
  359. FontName    dc.b    "topaz.font",0
  360. PortName    dc.b    "CacheClock.port",0
  361. TimerName    dc.b    "timer.device",0
  362. TrackName    dc.b    "trackdisk.device",0
  363.         even
  364.  
  365. ****************    Open the programs window & font
  366. * OpenMyWindow *
  367. ****************    returns d0=0, window open bad
  368. OpenMyWindow
  369.     lea    MyWindow(pc),a0
  370.     move.l    IntBase(pc),a6
  371.     jsr    OpenWindow(a6)
  372.  
  373.     move.l    d0,Window
  374.     beq.s    BadOpen
  375.     move.l    Window(pc),a0
  376.     move.l    wd_RPort(a0),RastPort    Get windows rastport
  377.     move.l    wd_UserPort(a0),a0
  378.     moveq    #0,d0
  379.     move.b    $f(a0),d0
  380.     moveq    #1,d1
  381.     asl.l    d0,d1
  382.     move.l    d1,Signals        Get windows signal
  383.  
  384.     lea    FontAttr(pc),a0        Open Topaz 8 font
  385.     move.l    GfxBase(pc),a6
  386.     jsr    OpenFont(a6)
  387.     move.l    d0,TopazFont
  388.     beq.s    NoFont
  389.  
  390.     move.l    d0,a0
  391.     move.l    RastPort(pc),a1        use that font
  392.     move.l    GfxBase(pc),a6
  393.     jsr    SetFont(a6)
  394. NoFont
  395.     move.l    a2,-(a7)
  396.     move.l    Window(pc),a0
  397.     lea    TitleName(pc),a1
  398.     lea    ScreenName(pc),a2
  399.     move.l    IntBase(pc),a6
  400.     jsr    SetWindowTitles(a6)
  401.     move.l    (a7)+,a2
  402.  
  403. BadOpen    move.l    Window(pc),d0
  404.     rts
  405.  
  406. *****************    Shut my window & font
  407. * CloseMyWindow *
  408. *****************
  409. CloseMyWindow
  410.     move.l    Window(pc),d0
  411.     beq.s    NoWind
  412.  
  413.     move.l    $4.w,a6
  414.  
  415. DelNMsg    move.l    Window(pc),a0        Reply to all unanswered messages
  416.     move.l    wd_UserPort(a0),a0
  417.     jsr    GetMsg(a6)
  418.  
  419.     tst.l    d0
  420.     beq.s    LastMsg
  421.     move.l    d0,a1
  422.     jsr    ReplyMsg(a6)
  423.     bra.s    DelNMsg
  424. LastMsg    
  425.  
  426.     move.l    Window(pc),a0
  427.     move.l    IntBase(pc),a6
  428.     jsr    CloseWindow(a6)
  429.  
  430. NoWind    move.l    TopazFont(pc),d0
  431.     beq.s    NoFnt
  432.     move.l    d0,a1
  433.     move.l    GfxBase(pc),a6
  434.     jsr    CloseFont(a6)
  435.  
  436. NoFnt    rts
  437.  
  438.  
  439. ************    Start timer running & request signal in 1 second
  440. * SetTimer *
  441. ************
  442. SetTimer
  443.     lea    TimerIOreq(pc),a1
  444.     move.w    #TR_ADDREQUEST,IO_COMMAND(a1)
  445.     move.l    #1,IOTV_TIME+TV_SECS(a1)
  446.     clr.l    IOTV_TIME+TV_MICRO(a1)
  447.     move.l    $4.w,a6
  448.     jmp    SendIO(a6)
  449.  
  450.  
  451. ***************    Opens timer B, and sets it to interrupt every 2 seconds
  452. * OpenMyTimer *
  453. ***************    returns d0=0, open timer failed
  454. OpenMyTimer
  455.     lea    TimerPort(pc),a2        Set up port for IO request
  456.     bsr    InitPort
  457.     tst.l    d0
  458.     beq.s    NoTimePort
  459.  
  460.     lea    TimerIOreq(pc),a1
  461.     move.b    #NT_MESSAGE,LN_TYPE(a1)        set up IO request structure
  462.     move.l    a2,MN_REPLYPORT(a1)
  463.     move.w    #IOSTD_SIZE,MN_LENGTH(a1)
  464.  
  465.     lea    TimerName(pc),a0    Open timer.device
  466.     moveq    #1,d0
  467.     moveq    #0,d1
  468.     move.l    $4.w,a6
  469.     jsr    OpenDevice(a6)
  470.     tst.l    d0
  471.     bne.s    NoTimerDevice
  472.  
  473.     lea    TimerPort(pc),a0    Get Timers signal
  474.     moveq    #0,d0
  475.     move.b    $f(a0),d0
  476.     moveq    #1,d1
  477.     asl.l    d0,d1
  478.     or.l    d1,Signals
  479.  
  480.     bsr    SetTimer        Set timer to interrupt in 2 secs
  481.  
  482.     moveq    #1,d0
  483. NoTimePort
  484.     rts
  485.  
  486. NoTimerDevice
  487.     lea    TimerPort(pc),a0
  488.     moveq    #0,d0            free signal bit used by port
  489.     move.b    MP_SIGBIT(a2),d0
  490.     move.l    $4.w,a6
  491.     jmp    FreeSignal(a6)
  492.  
  493.  
  494. ****************    Shuts down the use of timer.device
  495. * CloseMyTimer *
  496. ****************
  497. CloseMyTimer
  498.     lea    TimerIOreq(pc),a1    Timer still doing IO
  499.     move.l    $4.w,a6
  500.     jsr    CheckIO(a6)
  501.  
  502.     tst.l    d0
  503.     bne.s    FreeTimerMsg
  504.     lea    TimerIOreq(pc),a1    yes, so abort it
  505.     move.l    $4.w,a6
  506.     jsr    AbortIO(a6)
  507.  
  508. FreeTimerMsg
  509.     lea    TimerPort(pc),a0    Free messages used by port
  510.     jsr    GetMsg(a6)
  511.     tst.l    d0
  512.     bne.s    FreeTimerMsg
  513.  
  514.     lea    TimerIOreq(pc),a1    close timer.device
  515.     move.l    $4.w,a6
  516.     jsr    CloseDevice(a6)
  517.  
  518.     lea    TimerPort(pc),a0
  519.     moveq    #0,d0            free signal bit used by port
  520.     move.b    MP_SIGBIT(a2),d0
  521.     jmp    FreeSignal(a6)
  522.  
  523.  
  524. ************    Sets up port a2 and grabs a signal for it
  525. * InitPort *
  526. ************
  527. InitPort
  528.     clr.l    LN_NAME(a2)
  529.     clr.b    LN_PRI(a2)
  530.     move.b    #NT_MSGPORT,LN_TYPE
  531.     clr.b    MP_FLAGS(a2)
  532.  
  533.     moveq    #-1,d0
  534.     move.l    $4.w,a6
  535.     jsr    AllocSignal(a6)
  536.     cmp.l    #$ffffffff,d0
  537.     beq.s    NoSignals
  538.     move.b    d0,MP_SIGBIT(a2)
  539.  
  540.     sub.l    a1,a1
  541.     move.l    $4.w,a6
  542.     jsr    FindTask(a6)
  543.  
  544.     move.l    d0,MP_SIGTASK(a2)
  545.     lea    MP_MSGLIST(a2),a0
  546.     move.l    a0,(a0)
  547.     addq.l    #4,(a0)
  548.     clr.l    LH_TAIL(a0)
  549.     move.l    a0,LH_TAILPRED(a0)
  550.  
  551.     move.l    a2,d0
  552.     rts
  553. NoSignals
  554.     moveq    #0,d0
  555.     rts
  556.  
  557.  
  558. ********************    Gets library base for trackdisk.device
  559. * GetTrackdiskBase *
  560. ********************
  561. GetTrackdiskBase
  562.     move.l    a2,-(sp)
  563.  
  564.     lea    TrackdiskPort(pc),a2        Set up port for IO request
  565.     bsr    InitPort
  566.     tst.l    d0
  567.     beq.s    BadTrackPort
  568.  
  569.     lea    TrackdiskIOreq(pc),a1
  570.     move.b    #NT_MESSAGE,LN_TYPE(a1)        set up IO request structure
  571.     move.l    a2,MN_REPLYPORT(a1)
  572.     move.w    #IOSTD_SIZE,MN_LENGTH(a1)
  573.  
  574.     lea    TrackName(pc),a0        open trackdisk.device
  575.     moveq    #0,d0
  576.     moveq    #0,d1
  577.     move.l    $4.w,a6
  578.     jsr    OpenDevice(a6)
  579.     tst.l    d0
  580.     bne.s    BadTrackdisk
  581.  
  582.     lea    TrackdiskIOreq(pc),a0        Get trackdisk library offsets
  583.     move.l    IO_DEVICE(a0),TrackBase
  584.  
  585.     lea    TrackdiskIOreq(pc),a1        close trackdisk.device
  586.     move.l    $4.w,a6
  587.     jsr    CloseDevice(a6)
  588.  
  589. BadTrackdisk
  590.     moveq    #0,d0            free signal bit used by port
  591.     move.b    MP_SIGBIT(a2),d0
  592.     jsr    FreeSignal(a6)
  593.  
  594.     move.l    TrackBase(pc),d0
  595. BadTrackPort
  596.     move.l    (sp)+,a2
  597.     rts
  598.  
  599.  
  600. ******************
  601. * PatchTrackdisk *
  602. ******************
  603. PatchTrackdisk
  604.     move.l    $4.w,a6        Disable system
  605.     jsr    Forbid(a6)
  606.     jsr    Disable(a6)
  607.  
  608.     move.l    TrackBase(pc),a1    Install trackdisk patch
  609.     lea    -$1e.w,a0
  610.     move.l    #NewTrackDisk,d0
  611.     jsr    SetFunction(a6)
  612.     move.l    d0,OldTrackDisk+2
  613.  
  614.     jsr    Enable(a6)    Enable system
  615.     jmp    Permit(a6)
  616.  
  617.  
  618. ********************
  619. * RestoreTrackdisk *
  620. ********************
  621. RestoreTrackdisk
  622.     move.l    $4.w,a6        Disable system
  623.     jsr    Forbid(a6)
  624.     jsr    Disable(a6)
  625.  
  626.     move.l    TrackBase(pc),a1    restore trackdisk
  627.     lea    -$1e.w,a0
  628.     move.l    OldTrackDisk+2(pc),d0
  629.     jsr    SetFunction(a6)
  630.  
  631.     jsr    Enable(a6)    Enable system
  632.     jmp    Permit(a6)
  633.  
  634. DrawSmall    rts
  635.  
  636. *****************    Draws the outline for the big window
  637. * DrawBigWindow *
  638. *****************
  639. DrawBigWindow
  640.     move.b    GadgetSmall(pc),d0
  641.     bne.s    DrawSmall
  642.  
  643.     bsr    SetColour0        Clear big window
  644.     move.l    Window(pc),a0
  645.     moveq    #4,d0
  646.     moveq    #$c,d1
  647.     move.w    wd_Width(a0),d2
  648.     subq.w    #8,d2
  649.     move.w    wd_Height(a0),d3
  650.     subq.w    #3,d3
  651.     move.l    RastPort(pc),a1
  652.     move.l    GfxBase,a6
  653.     jsr    RectFill(a6)
  654.  
  655.     moveq    #$6,d0            Draw infotext panel
  656.     moveq    #$c,d1
  657.     moveq    #$5a,d2
  658.     moveq    #$46,d3
  659.     bsr    DrawPanel
  660.  
  661.     moveq    #$a,d0            Draw infotext underline
  662.     moveq    #$1b,d1
  663.     move.l    #$52,d2
  664.     moveq    #1,d3
  665.     bsr    DrawWb2Box
  666.  
  667.     moveq    #$64,d0            Draw drive stats panel
  668.     moveq    #$c,d1
  669.     move.l    #$f0,d2
  670.     moveq    #$46,d3
  671.     bsr    DrawPanel
  672.  
  673.     moveq    #$68,d0            draw drive stats underline
  674.     moveq    #$1b,d1
  675.     move.l    #$e8,d2
  676.     moveq    #1,d3
  677.     bsr    DrawWb2Box
  678.  
  679.     move.l    #$158,d0        Draw panel for totals
  680.     moveq    #$c,d1
  681.     moveq    #$4a,d2
  682.     moveq    #$46,d3
  683.     bsr    DrawPanel
  684.  
  685.     lea    InfoTx(pc),a2        Draw all text onto window
  686.     bsr    DrawTexts
  687.  
  688.     move.l    #$15c,d0
  689.     moveq    #$1b,d1
  690.     moveq    #$42,d2
  691.     moveq    #$1,d3
  692.     bsr    DrawWb2Box
  693.  
  694.     moveq    #$a,d0            Fewer box
  695.     moveq    #$57,d1
  696.     moveq    #$54,d2
  697.     moveq    #$c,d3
  698.     bsr    DrawWb2Box
  699.  
  700.     move.l    #$15b,d0        More box
  701.     moveq    #$57,d1
  702.     moveq    #$42,d2
  703.     moveq    #$c,d3
  704.     bsr    DrawWb2Box
  705.  
  706.     moveq    #$64,d0            Time & memory box
  707.     moveq    #$56,d1
  708.     move.l    #$f0,d2
  709.     moveq    #$e,d3
  710.     bra    DrawPanel
  711.  
  712. ****************    Check for gadget presses, and timer interrupts
  713. * CheckGagdets *
  714. ****************    returns d0 = 0, close window pressed
  715. CheckGadgets
  716.     movem.l    d4/a2/a3,-(a7)
  717.  
  718. NextWindowMsg
  719.     move.l    Window(pc),a0
  720.     move.l    wd_UserPort(a0),a0
  721.     move.l    $4.w,a6
  722.     jsr    GetMsg(a6)
  723.  
  724.     tst.l    d0
  725.     beq    CheckMoreFew
  726.     move.l    d0,a2
  727.     move.l    d0,a1
  728.     move.l    im_Class(a1),d4
  729.     move.l    im_IAddress(a1),a3
  730.     jsr    ReplyMsg(a6)
  731.  
  732.     cmp.l    #GADGETDOWN,d4            Check for fewer/more pressed
  733.     bne.s    NotGadDown
  734.     cmp.w    #MoreGadget,gg_GadgetID(a3)
  735.     bne.s    NoMoreP
  736.     st    MorePressed
  737. NoMoreP    cmp.w    #FewerGadget,gg_GadgetID(a3)
  738.     bne.s    NotGadDown
  739.     st    FewerPressed
  740.  
  741. NotGadDown
  742.     cmp.l    #GADGETUP,d4            Check for fewer/more released
  743.     bne.s    NotGadgetUp
  744.     cmp.w    #MoreGadget,gg_GadgetID(a3)
  745.     bne.s    NoMoreR
  746.     clr.b    MorePressed
  747. NoMoreR    cmp.w    #FewerGadget,gg_GadgetID(a3)
  748.     bne.s    NotGadgetUp
  749.     clr.b    FewerPressed
  750.  
  751. NotGadgetUp
  752.     cmp.l    #MENUPICK,d4
  753.     bne.s    NotMenuPick
  754.     move.b    GadgetSmall(pc),d0
  755.     beq.s    ToSmall
  756.     bsr    ExpandWindow        go big window
  757.     bra.s    NotMenuPick
  758. ToSmall    bsr    ShrinkWindow        go small window
  759.  
  760. NotMenuPick
  761.     cmp.l    #CLOSEWINDOW,d4            Check for Close window
  762.     beq.s    CloseWind
  763.  
  764. CheckMoreFew
  765.     move.b    MorePressed(pc),d0    Check for more pressed / released
  766.     beq.s    NoChkMore
  767.     btst    #7,MoreGadgFlags+1
  768.     bne.s    MoreHit
  769.     clr.b    MorePressed        more released
  770.     bra.s    NoChkFew
  771. MoreHit    bsr    AddSector        more still pressed
  772.  
  773. Refresh    bsr    RefreshStats
  774.     moveq    #1,d1
  775.     move.l    DosBase(pc),a6
  776.     jsr    Delay(a6)
  777.     bra    NextWindowMsg
  778.  
  779. FewerHit
  780.     bsr    FreeSector        fewer still pressed
  781.     bra.s    Refresh
  782.  
  783. NoChkMore
  784.     move.b    FewerPressed(pc),d0    Check for fewer pressed / released
  785.     beq.s    NoChkFew
  786.     btst    #7,FewerGadgFlags+1
  787.     bne.s    FewerHit
  788.     clr.b    FewerPressed        fewer released
  789. NoChkFew
  790.     moveq    #0,d0
  791.     bra.s    EndMsgs
  792.  
  793. CloseWind
  794.     moveq    #1,d0
  795. EndMsgs    movem.l    (a7)+,d4/a2/a3
  796.     rts
  797.  
  798. *************    Draws a panel at (d0,d1), width (d2,d3) & clears the insides
  799. * DrawPanel *
  800. *************
  801. DrawPanel
  802.     movem.l    d0/d1/d2/d3,-(sp)
  803.     bsr    DrawWb2Box
  804.     movem.l    (sp),d0/d1/d2/d3
  805.     addq.w    #1,d0
  806.     addq.w    #1,d1
  807.     subq.w    #2,d2
  808.     subq.w    #2,d3
  809.     bsr    DrawWb2Box
  810.  
  811.     bsr    SetColour0        Clear box just drawn
  812.     movem.l    (sp)+,d0/d1/d2/d3
  813.     add.w    d0,d2
  814.     add.w    d1,d3
  815.     addq.w    #3,d0
  816.     addq.w    #2,d1
  817.     subq.w    #3,d2
  818.     subq.w    #2,d3
  819.     move.l    RastPort(pc),a1
  820.     move.l    GfxBase,a6
  821.     jmp    RectFill(a6)
  822.  
  823.  
  824. *************    Displays onscreen a number of texts, from (a2)+
  825. * DrawTexts *
  826. *************
  827. DrawTexts
  828.     bsr    SetColour1
  829. DrawNextText
  830.     moveq    #0,d0
  831.     move.w    (a2)+,d0
  832.     cmp.w    #-1,d0
  833.     beq.s    EndDrawTexts
  834.     moveq    #0,d1
  835.     move.w    (a2)+,d1
  836.     move.l    RastPort(pc),a1
  837.     move.l    GfxBase(pc),a6
  838.     jsr    Move(a6)        move to start of text
  839.  
  840.     move.l    a2,a0
  841. ToEndSt    tst.b    (a2)+
  842.     bne.s    ToEndSt
  843.     move.l    a2,d0
  844.     sub.l    a0,d0
  845.     move.w    d0,d1        word align a0 to next text to draw
  846.     and.w    #1,d1
  847.     add.w    d1,a2
  848.  
  849.     subq.w    #1,d0
  850.     move.l    RastPort(pc),a1
  851.     move.l    GfxBase(pc),a6
  852.     jsr    Text(a6)
  853.     bra.s    DrawNextText
  854.  
  855. EndDrawTexts
  856.     rts
  857.  
  858.  
  859. InfoTx    dc.w    $1f,$18
  860.     dc.b    "Drive",0
  861.     dc.w    $1f,$26
  862.     dc.b    "Reads",0
  863.     dc.w    $1b,$30
  864.     dc.b    "Writes",0
  865.     dc.w    $17,$3a
  866.     dc.b    "ReadHits",0
  867.     dc.w    $b,$44
  868.     dc.b    "Percentage",0
  869.     dc.w    $15,$4e
  870.     dc.b    "Buffers",0
  871.  
  872.     dc.w    $80,$18
  873.     dc.b    "A",0
  874.     dc.w    $ba,$18
  875.     dc.b    "B",0
  876.     dc.w    $f4,$18
  877.     dc.b    "C",0
  878.     dc.w    $12e,$18
  879.     dc.b    "D",0
  880.  
  881.     dc.w    $21,$60
  882.     dc.b    "Fewer",0
  883.  
  884.     dc.w    $16d,$60
  885.     dc.b    "More",0
  886.  
  887.     
  888.     dc.w    $169,$19
  889.     dc.b    "Total",0
  890.     dc.w    -1
  891.  
  892.  
  893. SpacesTx    dc.b    "       ",0
  894.  
  895. TimeMemoryTx    dc.b    "Free:"
  896. MemoryStore    dc.b    "????????  Time:"
  897. TimeStore    dc.b    "??:??:??"
  898.  
  899. SmallMenu    dc.b    " Chip:"
  900. ChipAmount    dc.b    "???? Fast:"
  901. FastAmount    dc.b    "????? Time:"
  902. SmallTime    dc.b    "??:??:?? "
  903.  
  904. nums    dc.l    100000000,10000000,1000000,100000,10000,1000,100,10,1,-1
  905.  
  906. **************    writes number d0 into buffer (a1)
  907. * TextNumber *    leading zeros are omitted
  908. **************    returns d0 = length of string
  909. TextNumber
  910.     movem.l    d6/d7,-(sp)
  911.     move.l    a1,-(sp)
  912.  
  913.     moveq    #0,d7            d7 = 1, include zeros
  914.     lea    nums(pc),a0
  915.  
  916. NextDivisor
  917.     move.l    (a0)+,d1
  918.     bmi.s    NumberDone
  919.  
  920.     moveq    #"0",d6
  921. CompareAgain
  922.     cmp.l    d1,d0
  923.     blt.s    NoSubtract
  924.     addq.w    #1,d6
  925.     sub.l    d1,d0
  926.     moveq    #1,d7
  927.     bra.s    CompareAgain
  928. NoSubtract
  929.     tst.w    d7
  930.     beq.s    NextDivisor
  931.     move.b    d6,(a1)+        Add digit to display buffer
  932.     bra.s    NextDivisor
  933. NumberDone
  934.     tst.w    d7
  935.     bne.s    NumberNot0
  936.     move.b    #"0",(a1)+
  937. NumberNot0
  938.     clr.b    (a1)
  939.     sub.l    (sp)+,a1
  940.     move.l    a1,d0
  941.     movem.l    (sp)+,d6/d7
  942.     rts
  943.  
  944. NumberBuffer    ds.b    10
  945.  
  946. **********************    Displays number (d2) at (d0,d1)
  947. * PrintCentralNumber *
  948. **********************
  949. PrintCentralNumber
  950.     movem.l    d0/d1/d2/d3,-(sp)
  951.  
  952.     move.l    RastPort(pc),a1        Clear space for number to go in
  953.     move.l    GfxBase,a6
  954.     jsr    Move(a6)
  955.  
  956.     lea    SpacesTx(pc),a0
  957.     moveq    #7,d0
  958.     move.l    RastPort(pc),a1
  959.     move.l    GfxBase(pc),a6
  960.     jsr    Text(a6)
  961.  
  962.     move.l    $8(sp),d0        Convert number to ascii
  963.     lea    NumberBuffer(pc),a1
  964.     bsr    TextNumber
  965.     move.l    d0,d3
  966.  
  967.     lea    NumberBuffer(pc),a0    Get length of string in pixels
  968.     move.l    RastPort(pc),a1
  969.     move.l    GfxBase(pc),a6
  970.     jsr    TextLength(a6)
  971.  
  972.     lsr.l    #1,d0
  973.  
  974.     moveq    #$3a,d1
  975.     sub.l    d0,d1
  976.     move.l    d1,d0
  977.  
  978.     add.l    (sp),d0
  979.     sub.l    #$1e,d0
  980.     move.l    4(sp),d1
  981.     move.l    RastPort(pc),a1
  982.     move.l    GfxBase,a6
  983.     jsr    Move(a6)
  984.  
  985.     lea    NumberBuffer(pc),a0
  986.     move.l    d3,d0
  987.     move.l    RastPort(pc),a1
  988.     move.l    GfxBase(pc),a6
  989.     jsr    Text(a6)
  990.     movem.l    (sp)+,d0/d1/d2/d3
  991.     rts
  992.  
  993.  
  994. **************    converts system date into ascii values from (a0)+
  995. * GetSysTime *
  996. **************
  997. GetSysTime
  998.     move.l    a0,-(sp)
  999.     move.l    #Date,d1
  1000.     move.l    DosBase(pc),a6
  1001.     jsr    DateStamp(a6)
  1002.     lea    Date(pc),a0
  1003.     move.l    (sp)+,a1
  1004.  
  1005.     move.l    ds_Minute(a0),d0
  1006.     moveq    #"0",d1            Work out tens of hours
  1007. CalcHT    cmp.l    #600,d0
  1008.     blt.s    EndHrT
  1009.     addq.w    #1,d1
  1010.     sub.l    #600,d0
  1011.     bra.s    CalcHT
  1012. EndHrT    move.b    d1,(a1)
  1013.     moveq    #"0",d1
  1014. CalcHrs    cmp.l    #60,d0            work out hours
  1015.     blt.s    EndHrs
  1016.     addq.w    #1,d1
  1017.     sub.l    #60,d0
  1018.     bra.s    CalcHrs
  1019. EndHrs    move.b    d1,1(a1)
  1020.     moveq    #"0",d1
  1021. CalcMT    cmp.l    #10,d0            work out tens of minutes
  1022.     blt.s    EndMinT
  1023.     addq.w    #1,d1
  1024.     sub.l    #10,d0
  1025.     bra.s    CalcMT
  1026. EndMinT    move.b    d1,3(a1)
  1027.     add.w    #$30,d0            get minutes
  1028.     move.b    d0,4(a1)
  1029.  
  1030.     move.l    ds_Tick(a0),d0
  1031.     moveq    #"0",d1
  1032. CalcST    cmp.l    #500,d0            work out tens of seconds
  1033.     blt.s    EndSecT
  1034.     addq.w    #1,d1
  1035.     sub.l    #500,d0
  1036.     bra.s    CalcST
  1037. EndSecT    move.b    d1,6(a1)
  1038.     moveq    #"0",d1
  1039. CalcSec    cmp.l    #50,d0            work out seconds
  1040.     blt.s    EndSecs
  1041.     addq.w    #1,d1
  1042.     sub.l    #50,d0
  1043.     bra.s    CalcSec
  1044. EndSecs    move.b    d1,7(a1)
  1045.     rts
  1046.  
  1047.  
  1048. ****************    Redraws numbers on screen if needed
  1049. * RefreshStats *
  1050. ****************
  1051. RefreshStats
  1052.     bsr    SetColour1
  1053.     move.b    GadgetSmall(pc),d0
  1054.     bne.s    SmallRefresh
  1055.  
  1056.     bsr    DisplayMemoryTime
  1057.     bsr    DisplayReads
  1058.     bsr    DisplayWrites
  1059.     bsr    DisplayReadHits
  1060.     bsr    DisplayBuffers
  1061.     rts
  1062. SmallRefresh
  1063.     lea    ChipAmount(pc),a0
  1064.     moveq    #4,d0
  1065. ClrMems    move.b    #" ",0(a0,d0.w)
  1066.     move.b    #" ",FastAmount-ChipAmount+1(a0,d0.w)
  1067.     dbra    d0,ClrMems
  1068.     move.b    #" ",FastAmount-ChipAmount(a0)
  1069.  
  1070.     moveq    #2,d1            Get amount of chip ram
  1071.     move.l    $4.w,a6
  1072.     jsr    AvailMem(a6)
  1073.     moveq    #10,d1
  1074.     lsr.l    d1,d0
  1075.     lea    ChipAmount(pc),a1    Copy Chip amount
  1076.     bsr    TextNumber
  1077.     lea    ChipAmount(pc),a1    change \0 to a space
  1078.     move.b    #" ",0(a1,d0.w)
  1079.  
  1080.     moveq    #4,d1            Get amount of fast ram
  1081.     move.l    $4.w,a6
  1082.     jsr    AvailMem(a6)
  1083.     moveq    #10,d1
  1084.     lsr.l    d1,d0
  1085.     lea    FastAmount(pc),a1    Copy fast amount
  1086.     bsr    TextNumber
  1087.     lea    FastAmount(pc),a1
  1088.     move.b    #" ",0(a1,d0.w)        change \0 to a space
  1089.  
  1090.     lea    SmallTime(pc),a0
  1091.     bsr    GetSysTime
  1092.     moveq    #$1d,d0
  1093.     moveq    #$7,d1
  1094.     move.l    RastPort(pc),a1
  1095.     move.l    GfxBase,a6
  1096.     jsr    Move(a6)
  1097.  
  1098.  
  1099.     lea    SmallMenu(pc),a0    Display time & memory left
  1100.     moveq    #36,d0
  1101.     move.l    RastPort(pc),a1
  1102.     move.l    GfxBase(pc),a6
  1103.     jmp    Text(a6)
  1104.  
  1105.  
  1106. *********************    Displays memory, time and totals
  1107. * DisplayMemoryTime *
  1108. *********************
  1109. DisplayMemoryTime
  1110.     movem.l    d2/d4,-(sp)
  1111.     lea    MemoryStore(pc),a0    Clear last memory count
  1112.     moveq    #8,d0
  1113. ClrMemSt
  1114.     move.b    #" ",0(a0,d0.w)
  1115.     dbra    d0,ClrMemSt
  1116.  
  1117.     moveq    #2,d1            Get amount of chip ram
  1118.     move.l    $4.w,a6
  1119.     jsr    AvailMem(a6)
  1120.     move.l    d0,d4
  1121.     moveq    #4,d1            Add to the amount of fast ram
  1122.     jsr    AvailMem(a6)
  1123.     add.l    d4,d0
  1124.  
  1125.     lea    MemoryStore(pc),a1    Copy memory number
  1126.     bsr    TextNumber
  1127.     lea    MemoryStore(pc),a1    Copy memory number
  1128.     move.b    #" ",0(a1,d0.w)
  1129.  
  1130.     lea    TimeStore(pc),a0
  1131.     bsr    GetSysTime
  1132.  
  1133.     moveq    #$6c,d0
  1134.     moveq    #$60,d1
  1135.     move.l    RastPort(pc),a1
  1136.     move.l    GfxBase,a6
  1137.     jsr    Move(a6)
  1138.  
  1139.  
  1140.     lea    TimeMemoryTx(pc),a0    Display time & memory left
  1141.     moveq    #28,d0
  1142.     move.l    RastPort(pc),a1
  1143.     move.l    GfxBase(pc),a6
  1144.     jsr    Text(a6)
  1145.  
  1146.  
  1147.     move.l    TotalReads(pc),d2    Display number of reads if changed
  1148.     move.b    ForcePrint(pc),d0        Must print ?
  1149.     bne.s    FrceRds
  1150.     cmp.l    LastTotalReads(pc),d2
  1151.     beq.s    ReadsSame
  1152. FrceRds    move.l    d2,LastTotalReads
  1153.  
  1154.     move.l    #$161,d0
  1155.     moveq    #$26,d1
  1156.     bsr    PrintCentralNumber
  1157.  
  1158. ReadsSame
  1159.     move.l    TotalWrites(pc),d2    Display number of writes if changed
  1160.     move.b    ForcePrint(pc),d0        Must print ?
  1161.     bne.s    FrceWts
  1162.     cmp.l    LastTotalWrites(pc),d2
  1163.     beq.s    WritesSame
  1164. FrceWts    move.l    d2,LastTotalWrites
  1165.  
  1166.     move.l    #$161,d0
  1167.     moveq    #$30,d1
  1168.     bsr    PrintCentralNumber
  1169.  
  1170. WritesSame
  1171.     move.l    TotalRHits(pc),d2    Display number of readhits if changed
  1172.     move.b    ForcePrint(pc),d0        Must print ?
  1173.     bne.s    FrceRHt
  1174.     cmp.l    LastTotalRHits(pc),d2
  1175.     beq.s    RHitsSame
  1176. FrceRHt    move.l    d2,LastTotalRHits
  1177.  
  1178.     move.l    #$161,d0
  1179.     moveq    #$3a,d1
  1180.     bsr    PrintCentralNumber
  1181.  
  1182. RHitsSame
  1183.  
  1184.     move.l    NumBlocks(pc),d2    Display number of blocks if changed
  1185.     move.b    ForcePrint(pc),d0        Must print ?
  1186.     bne.s    FrceBlk
  1187.     cmp.l    LastNumBlocks(pc),d2
  1188.     beq.s    BlocksSame
  1189. FrceBlk    move.l    d2,LastNumBlocks
  1190.  
  1191.     move.l    #$161,d0
  1192.     moveq    #$4e,d1
  1193.     bsr    PrintCentralNumber
  1194.  
  1195. BlocksSame
  1196.     movem.l    (sp)+,d2/d4
  1197.     rts
  1198.  
  1199. ****************    Displays the number of Reads
  1200. * DisplayReads *
  1201. ****************
  1202. DisplayReads
  1203.     movem.l    d2/d4,-(a7)
  1204.     moveq    #0,d4
  1205.  
  1206. DispNxtRead
  1207.     move.l    d4,d0
  1208.     add.l    d0,d0
  1209.     add.l    d0,d0
  1210.     lea    NumReads(pc),a0
  1211.     move.l    0(a0,d0.w),d2
  1212.  
  1213.     move.b    ForcePrint(pc),d1        Must print ?
  1214.     bne.s    FrceRd
  1215.  
  1216.     cmp.l    $10(a0,d0.w),d2
  1217.     beq.s    NoReadChange
  1218. FrceRd    move.l    d2,$10(a0,d0.w)
  1219.  
  1220.     move.l    d4,d0            Work out X position
  1221.     mulu    #$3a,d0
  1222.     add.l    #$68,d0
  1223.     move.l    d0,-(sp)        Save X pos for printing percentage
  1224.     moveq    #$26,d1
  1225.     bsr    PrintCentralNumber
  1226.  
  1227.     move.l    d4,d0            Work out percentage
  1228.     add.l    d0,d0            = ReadHits*100/Reads
  1229.     add.l    d0,d0
  1230.     lea    NumReads(pc),a0
  1231.     move.l    0(a0,d0.l),d1        Trap for division by 0
  1232.     beq.s    Reads0
  1233.     move.l    d1,-(sp)
  1234.     lea    NumReadHits(pc),a0
  1235.     move.l    0(a0,d0.l),d0
  1236.     moveq    #100,d1
  1237.     jsr    LongMult
  1238.     move.l    d0,d1
  1239.     move.l    (sp)+,d0
  1240.     jsr    LongDivide
  1241.     move.l    d0,d2
  1242.     bra.s    ReadsN
  1243. Reads0    moveq    #0,d2
  1244.  
  1245. ReadsN    move.l    (sp)+,d0        Display percentage
  1246.     moveq    #$44,d1
  1247.     bsr    PrintCentralNumber
  1248.  
  1249. NoReadChange
  1250.     addq.l    #1,d4
  1251.     cmp.l    #4,d4
  1252.     bne.s    DispNxtRead
  1253.     movem.l    (a7)+,d2/d4
  1254.     rts
  1255.  
  1256. *****************    Displays the number of Writes
  1257. * DisplayWrites *
  1258. *****************
  1259. DisplayWrites
  1260.     movem.l    d2/d4,-(a7)
  1261.     moveq    #0,d4
  1262.  
  1263. DispNxtWrite
  1264.     move.l    d4,d0
  1265.     asl.l    #2,d0
  1266.     lea    NumWrites(pc),a0
  1267.     move.l    0(a0,d0.w),d2
  1268.  
  1269.     move.b    ForcePrint(pc),d1        Must print ?
  1270.     bne.s    FrceWte
  1271.  
  1272.     cmp.l    $10(a0,d0.w),d2
  1273.     beq.s    NoWriteChange
  1274. FrceWte    move.l    d2,$10(a0,d0.w)
  1275.  
  1276.     move.l    d4,d0
  1277.     mulu    #$3a,d0
  1278.     add.l    #$68,d0
  1279.     moveq    #$30,d1
  1280.     bsr    PrintCentralNumber
  1281.  
  1282. NoWriteChange
  1283.     addq.l    #1,d4
  1284.     cmp.l    #4,d4
  1285.     bne.s    DispNxtWrite
  1286.     movem.l    (a7)+,d2/d4
  1287.     rts
  1288.  
  1289. *******************    Displays the number of Read hits
  1290. * DisplayReadHits *
  1291. *******************
  1292. DisplayReadHits
  1293.     movem.l    d2/d4,-(a7)
  1294.     moveq    #0,d4
  1295.  
  1296. DispNxtReadHit
  1297.     move.l    d4,d0
  1298.     asl.l    #2,d0
  1299.     lea    NumReadHits(pc),a0
  1300.     move.l    0(a0,d0.w),d2
  1301.  
  1302.     move.b    ForcePrint(pc),d1        Must print ?
  1303.     bne.s    FrceRdH
  1304.  
  1305.     cmp.l    $10(a0,d0.w),d2
  1306.     beq.s    NoReadHitChange
  1307. FrceRdH    move.l    d2,$10(a0,d0.w)
  1308.  
  1309.     move.l    d4,d0
  1310.     mulu    #$3a,d0
  1311.     add.l    #$68,d0
  1312.     moveq    #$3a,d1
  1313.     bsr    PrintCentralNumber
  1314.  
  1315. NoReadHitChange
  1316.     addq.l    #1,d4
  1317.     cmp.l    #4,d4
  1318.     bne.s    DispNxtReadHit
  1319.     movem.l    (a7)+,d2/d4
  1320.     rts
  1321.  
  1322. ******************    Displays the number of buffers
  1323. * DisplayBuffers *
  1324. ******************
  1325. DisplayBuffers
  1326.     movem.l    d2/d4,-(a7)
  1327.     moveq    #0,d4
  1328.  
  1329. DispNxtBuf
  1330.     move.l    d4,d0
  1331.     asl.l    #2,d0
  1332.     lea    NumBuffers(pc),a0
  1333.     move.l    0(a0,d0.w),d2
  1334.  
  1335.     move.b    ForcePrint(pc),d1        Must print ?
  1336.     bne.s    FrceBuf
  1337.  
  1338.     cmp.l    $10(a0,d0.w),d2
  1339.     beq.s    NoBufChange
  1340. FrceBuf    move.l    d2,$10(a0,d0.w)
  1341.  
  1342.     move.l    d4,d0
  1343.     mulu    #$3a,d0
  1344.     add.l    #$68,d0
  1345.     moveq    #$4e,d1
  1346.     bsr    PrintCentralNumber
  1347.  
  1348. NoBufChange
  1349.     addq.l    #1,d4
  1350.     cmp.l    #4,d4
  1351.     bne.s    DispNxtBuf
  1352.     movem.l    (a7)+,d2/d4
  1353.     rts
  1354.  
  1355.  
  1356. **************    Draws a workbench 2 style box at (d0,d1) width (d2,d3)
  1357. * DrawWb2Box *
  1358. **************
  1359. DrawWb2Box
  1360.     add.l    d0,d2
  1361.     add.l    d1,d3
  1362.     movem.l    d0/d1/d2/d3,-(sp)
  1363.  
  1364.     move.l    d3,d1
  1365.     move.l    RastPort(pc),a1
  1366.     move.l    GfxBase(pc),a6
  1367.     jsr    Move(a6)
  1368.     bsr    SetColour2
  1369.     movem.l    (sp),d0/d1
  1370.     move.l    RastPort(pc),a1
  1371.     jsr    Draw(a6)
  1372.     move.l    8(sp),d0
  1373.     move.l    4(sp),d1
  1374.     move.l    RastPort(pc),a1
  1375.     jsr    Draw(a6)
  1376.  
  1377.     bsr    SetColour1
  1378.     move.l    RastPort(pc),a1
  1379.     movem.l    8(sp),d0/d1
  1380.     move.l    RastPort(pc),a1
  1381.     jsr    Draw(a6)
  1382.  
  1383.     move.l    (sp),d0
  1384.     move.l    12(sp),d1
  1385.     move.l    RastPort(pc),a1
  1386.     jsr    Draw(a6)
  1387.     lea    $10(sp),sp
  1388.     rts
  1389.  
  1390.  
  1391.  
  1392. ****************    Changes window to the large one with stats
  1393. * ExpandWindow *
  1394. ****************
  1395. ExpandWindow
  1396.     move.b    GadgetSmall(pc),d0
  1397.     beq    WindowAlreadyBig
  1398.     clr.b    GadgetSmall
  1399.  
  1400.     move.l    Window(pc),a0
  1401.     move.l    wd_WScreen(a0),a1
  1402.  
  1403.     move.w    $c(a1),d0        Check for enough room in X direction
  1404.     sub.w    wd_LeftEdge(a0),d0
  1405.     sub.w    #$1aa,d0
  1406.     ext.l    d0
  1407.     bmi.s    XposBAD
  1408.     moveq    #0,d0
  1409. XposBAD
  1410.  
  1411.     move.w    $e(a1),d1        Check for enough room in Y direction
  1412.     sub.w    wd_TopEdge(a0),d1
  1413.     sub.w    #$70,d1
  1414.     ext.l    d1
  1415.     bmi.s    YposBAD
  1416.     moveq    #0,d1
  1417. YposBAD
  1418.     tst.l    d0
  1419.     bne.s    MvWindo
  1420.     tst.l    d1
  1421.     beq.s    NoMoveWindow
  1422.  
  1423. MvWindo    move.l    wd_LeftEdge(a0),-(sp)    Not enough room, so move window
  1424.  
  1425.     move.l    IntBase(pc),a6
  1426.     jsr    MoveWindow(a6)
  1427.  
  1428. CheckWindowMoved
  1429.     move.l    Window(pc),a0        Window been moved yet
  1430.     move.l    wd_LeftEdge(a0),d0
  1431.     cmp.l    (sp),d0
  1432.     bne.s    MvdWind
  1433.     moveq    #1,d1            no, so wait a tick
  1434.     move.l    DosBase(pc),a6
  1435.     jsr    Delay(a6)
  1436.     bra.s    CheckWindowMoved
  1437. MvdWind    addq.w    #4,sp
  1438.  
  1439. NoMoveWindow
  1440.     moveq    #WindowBigX-WindowSmallX,d0
  1441.     moveq    #WindowBigY-WindowSmallY,d1
  1442.     move.l    Window(pc),a0
  1443.     move.l    IntBase(pc),a6
  1444.     jsr    SizeWindow(a6)
  1445.  
  1446. WaitExpandWind
  1447.     move.l    Window(pc),a0        Wait for window to expand
  1448.     cmp.w    #WindowBigX,wd_Width(a0)
  1449.     beq.s    WindowExpanded
  1450.     moveq    #1,d1
  1451.     move.l    DosBase(pc),a6
  1452.     jsr    Delay(a6)
  1453.     bra.s    WaitExpandWind
  1454.  
  1455. WindowExpanded
  1456.     bsr    DrawBigWindow
  1457.     st    ForcePrint
  1458.     bsr    RefreshStats
  1459.     clr    ForcePrint
  1460.  
  1461. WindowAlreadyBig
  1462.     rts
  1463.  
  1464. ****************    shrinks the window to the small sized one
  1465. * ShrinkWindow *
  1466. ****************
  1467. ShrinkWindow
  1468.     move.b    GadgetSmall(pc),d0    Is window already small ?
  1469.     bne    WindowAlreadySmall
  1470.     st    GadgetSmall
  1471.  
  1472.     moveq    #WindowSmallX-WindowBigX,d0        No, so shrink it
  1473.     moveq    #WindowSmallY-WindowBigY,d1
  1474.     move.l    Window(pc),a0
  1475.     move.l    IntBase(pc),a6
  1476.     jsr    SizeWindow(a6)
  1477.  
  1478. WindowAlreadySmall
  1479.     rts
  1480.  
  1481. **************    Searchs hash list for sector IO_OFFSET(a1), drive d2
  1482. * FindSector *    d0 = 0, search failed. d0=1, a0=Sector
  1483. **************
  1484. FindSector
  1485.     move.l    IO_OFFSET(a1),d0
  1486.     lsr.l    #7,d0
  1487.     and.l    #$1fc,d0
  1488.     lea    SectorHeaders(pc),a2
  1489.     add.w    d0,a2
  1490.     move.l    (a2),d0
  1491. SearchHash
  1492.     beq.s    NoSector
  1493.     move.l    d0,a0
  1494.     cmp.w    WhichDrive(a0),d2
  1495.     bne.s    WrongSector
  1496.     move.l    SectorOffset(a0),d0
  1497.     cmp.l    IO_OFFSET(a1),d0
  1498.     beq.s    RightSector
  1499. WrongSector
  1500.     move.l    NextHash(a0),d0
  1501.     bra.s    SearchHash
  1502. RightSector
  1503.     moveq    #1,d0
  1504.     rts
  1505.  
  1506. NoSector
  1507.     rts
  1508.  
  1509. ****************  Trackdisk patch, so that all read / writes are logged
  1510. * NewTrackDisk * and cached if possible
  1511. ****************
  1512. NewTrackDisk
  1513.     movem.l    d2/a2,-(a7)
  1514.  
  1515.     move.l    IO_UNIT(a1),d1        Add current unit to list of drives
  1516.     lea    DevUnits(pc),a0
  1517.     moveq    #0,d2            d2 = current drive number * 4
  1518. TryNdev    tst.l    (a0)
  1519.     bne.s    IsDvice
  1520.     move.l    d1,(a0)
  1521.     bra.s    FoundDevice
  1522.  
  1523. IsDvice    cmp.l    (a0)+,d1
  1524.     beq.s    FoundDevice
  1525.     addq.w    #4,d2
  1526.     cmp.w    #$10,d2
  1527.     bne.s    TryNdev
  1528. FoundDevice
  1529.  
  1530.     cmp.w    #CMD_READ,IO_COMMAND(a1)
  1531.     bne.s    NotCMD_READ
  1532.     addq.l    #1,TotalReads            reading sector
  1533.     lea    NumReads(pc),a0
  1534.     addq.l    #1,0(a0,d2.w)
  1535.  
  1536.     bsr.s    FindSector            sector in cache ?
  1537.     beq.s    IgnoreCMD
  1538.  
  1539.     bsr    ReadFromCache            yes, so copy it
  1540.     bra    DoneIO
  1541.  
  1542. NotCMD_READ
  1543.     cmp.w    #CMD_WRITE,IO_COMMAND(a1)
  1544.     bne.s    NotCMD_WRITE
  1545.     addq.l    #1,TotalWrites            writing sector
  1546.     lea    NumWrites(pc),a0
  1547.     addq.l    #1,0(a0,d2.w)
  1548.     bsr    WriteToCache
  1549.     bra.s    IgnoreCMD
  1550.  
  1551. NotCMD_WRITE
  1552.     cmp.w    #CMD_CLEAR,IO_COMMAND(a1)
  1553.     bne.s    IgnoreCMD
  1554.     bsr    DiskChange            disk change
  1555.  
  1556. IgnoreCMD
  1557.     move.l    a1,-(a7)
  1558. OldTrackDisk
  1559.     jsr    $0
  1560.     move.l    (a7)+,a1
  1561.  
  1562.     cmp.w    #CMD_READ,IO_COMMAND(a1)
  1563.     bne.s    DoneIO
  1564.     bsr    SaveReadSector
  1565.  
  1566. DoneIO    movem.l    (a7)+,d2/a2
  1567.     rts
  1568.  
  1569.  
  1570. *************    Adds a sector to the list of sectors
  1571. * AddSector *
  1572. *************    returns d0=0, ran out of memory
  1573. AddSector
  1574.     move.l    a2,-(a7)
  1575.     move.l    #$10001,d1
  1576.     move.l    #SectorSize,d0
  1577.     move.l    $4.w,a6
  1578.     jsr    AllocMem(a6)
  1579.  
  1580.     move.l    d0,a2
  1581.     beq.s    NoMemAddSec
  1582.  
  1583.     jsr    Forbid(a6)
  1584.  
  1585.     move.l    UnusedSectors(pc),NextInList(a2)
  1586.     move.l    a2,UnusedSectors
  1587.  
  1588.     jsr    Permit(a6)
  1589.     addq.l    #1,NumBlocks
  1590.     moveq    #1,d0
  1591.  
  1592. NoMemAddSec
  1593.     move.l    (a7)+,a2
  1594.     rts
  1595.  
  1596. *********************    Adds 256 sectors to the sector list
  1597. * AddDefaultSectors *
  1598. *********************
  1599. AddDefaultSectors
  1600.     move.l    #DefaultBuffers,d2
  1601.     beq.s    MemAddErr
  1602. AddNxSec
  1603.     bsr.s    AddSector
  1604.     tst.l    d0
  1605.     beq.s    MemAddErr
  1606.     subq.l    #1,d2
  1607.     bne.s    AddNxSec
  1608. MemAddErr
  1609.     rts
  1610.  
  1611.  
  1612. **************    Frees One sector used by the program
  1613. * FreeSector *
  1614. **************    returns d0 = sector to free
  1615. FreeSector
  1616.     move.l    a3,-(sp)
  1617.     move.l    $4.w,a6
  1618.     jsr    Forbid(a6)
  1619.  
  1620.     move.l    UnusedSectors(pc),d0
  1621.     beq.s    DeAlcSector
  1622.     move.l    d0,a3
  1623.     move.l    NextInList(a3),UnusedSectors
  1624.     bra.s    FreeSec
  1625.  
  1626. DeAlcSector
  1627.     move.l    LastSector(pc),d0
  1628.     beq.s    NoSects
  1629.     move.l    d0,a3
  1630.     bsr    RemoveSector
  1631.     move.w    WhichDrive(a3),d0
  1632.     lea    NumBuffers(pc),a0
  1633.     subq.l    #1,0(a0,d0.w)
  1634. FreeSec
  1635.     subq.l    #1,NumBlocks
  1636.     move.l    a3,a1
  1637.     move.l    #SectorSize,d0
  1638.     jsr    FreeMem(a6)
  1639.     move.l    a3,d0
  1640.  
  1641. NoSects    jsr    Permit(a6)
  1642.     move.l    (sp)+,a3
  1643.     rts
  1644.  
  1645.  
  1646. **************    Copies $200 bytes from (a0)+ to (a1)+
  1647. * CopySector *
  1648. **************
  1649. CopySector
  1650.     movem.l    d0/d1/d2/d3/d4/d5/d6/d7/a2/a3/a4/a5/a6,-(a7)
  1651.     REPT    9
  1652.     movem.l    (a0)+,d0/d1/d2/d3/d4/d5/d6/d7/a2/a3/a4/a5/a6
  1653.     movem.l    d0/d1/d2/d3/d4/d5/d6/d7/a2/a3/a4/a5/a6,(a1)
  1654.     lea    $34(a1),a1
  1655.     ENDR
  1656.     movem.l    (a0)+,d0/d1/d2/d3/d4/d5/d6/d7/a2/a3/a4
  1657.     movem.l    d0/d1/d2/d3/d4/d5/d6/d7/a2/a3/a4,(a1)
  1658.     movem.l    (a7)+,d0/d1/d2/d3/d4/d5/d6/d7/a2/a3/a4/a5/a6
  1659.     rts
  1660.  
  1661. **************** Removes Sector a3 from sector list.
  1662. * RemoveSector *
  1663. ****************
  1664. RemoveSector
  1665.     move.l    NextHash(a3),d0        Remove sector from hash list
  1666.     beq.s    NoNxHash
  1667.     move.l    d0,a0
  1668.     move.l    PrevHash(a3),PrevHash(a0)
  1669. NoNxHash
  1670.     move.l    PrevHash(a3),a0
  1671.     move.l    d0,NextHash(a0)
  1672.  
  1673.     move.l    NextInList(a3),d0    Remove sector from sector list
  1674.     beq.s    NoNext
  1675.     move.l    d0,a0
  1676.     move.l    PrevInList(a3),PrevInList(a0)
  1677. DoPrev    move.l    PrevInList(a3),d0
  1678.     beq.s    NoPriorSec
  1679.     move.l    d0,a0
  1680.     move.l    NextInList(a3),NextInList(a0)
  1681.     rts
  1682. NoNext    move.l    PrevInList(a3),LastSector    Deleting last sector in list
  1683.     bra.s    DoPrev
  1684. NoPriorSec
  1685.     move.l    NextInList(a3),FirstSector    Deleting first sector in list
  1686.     rts
  1687.  
  1688.  
  1689. **************** Inserts sector a3 into cache list at 1st position
  1690. * Add1stSector * a2 = Hash chain to add to
  1691. ****************
  1692. Add1stSector
  1693.     move.l    (a2),d0        Insert sector into hash chain
  1694.     beq.s    No2ndHash
  1695.     move.l    d0,a0
  1696.     move.l    a3,PrevHash(a0)
  1697. No2ndHash
  1698.     move.l    a3,(a2)
  1699.     move.l    a2,PrevHash(a3)
  1700.     move.l    d0,NextHash(a3)
  1701.  
  1702.     move.l    FirstSector(pc),d0    Insert sector into sector list
  1703.  
  1704.     move.l    a3,FirstSector
  1705.     clr.l    PrevInList(a3)
  1706.     move.l    d0,NextInList(a3)
  1707.     bne.s    Not1stSec
  1708.     move.l    a3,LastSector
  1709.     rts
  1710. Not1stSec
  1711.     move.l    d0,a0
  1712.     move.l    a3,PrevInList(a0)
  1713.     rts
  1714.  
  1715.  
  1716. *****************    Read sector from cache
  1717. * ReadFromCache *
  1718. *****************
  1719. ReadFromCache
  1720.     movem.l    a3/a4/a6,-(a7)
  1721.     move.l    a0,a3
  1722.     move.l    a1,a4
  1723.     move.l    $4.w,a6
  1724.     jsr    Forbid(a6)
  1725.     bsr    RemoveSector
  1726.     bsr.s    Add1stSector
  1727.  
  1728.     lea    Sector(a3),a0
  1729.     move.l    IO_DATA(a4),a1
  1730.     bsr    CopySector
  1731.  
  1732.     clr.b    IO_ERROR(a4)
  1733.     move.l    #$200,IO_SIZE(a4)
  1734.     addq.l    #1,TotalRHits
  1735.  
  1736.     lea    NumReadHits(pc),a0
  1737.     addq.l    #1,0(a0,d2.w)
  1738.  
  1739.     btst    #1,IO_FLAGS(a4)
  1740.     bne.s    NoRdMsg
  1741.     and.b    #$fe,IO_FLAGS(a4)    SendIO, so send done message
  1742.     move.l    a4,a1
  1743.     jsr    ReplyMsg(a6)
  1744. NoRdMsg    move.l    a4,a1
  1745.     jsr    Permit(a6)
  1746.     movem.l    (a7)+,a3/a4/a6
  1747.     rts
  1748.  
  1749. **************** Copies data from sector to be written into a buffer
  1750. * WriteToCache *
  1751. ****************
  1752. WriteToCache
  1753.     movem.l    a1/a3/a4/a6,-(a7)
  1754.     move.l    a1,a4
  1755.     move.l    $4.w,a6
  1756.     jsr    Forbid(a6)
  1757.     move.l    a4,a1
  1758.     bsr    FindSector
  1759.     beq.s    WriteToSector
  1760.  
  1761.     move.l    a0,a3
  1762.     bsr    RemoveSector
  1763.  
  1764. InsertWrite
  1765.     bsr    Add1stSector
  1766.  
  1767.     move.l    IO_DATA(a4),a0
  1768.     lea    Sector(a3),a1
  1769.     bsr    CopySector
  1770. NoWtStrucs
  1771.     jsr    Permit(a6)
  1772.     movem.l    (sp)+,a1/a3/a4/a6
  1773.     rts
  1774.  
  1775. WriteToSector
  1776.     bsr    AllocateSector
  1777.     tst.l    d0
  1778.     beq.s    NoWtStrucs
  1779.     bra.s    InsertWrite
  1780.  
  1781.  
  1782. **************    Disk changed, so flush all buffers used by drive d2
  1783. * DiskChange *
  1784. **************
  1785. DiskChange
  1786.     movem.l    a3/a4/a6,-(a7)
  1787.     move.l    $4.w,a6
  1788.     jsr    Forbid(a6)
  1789.  
  1790.     lea    NumBuffers(pc),a4
  1791.     lea    0(a4,d2.w),a4
  1792.  
  1793.     move.l    FirstSector(pc),a3
  1794. FreeNextSec
  1795.     move.l    a3,d0
  1796.     beq.s    EndDelSectors
  1797.     cmp.w    WhichDrive(a3),d2
  1798.     bne.s    SkipSector
  1799.     subq.l    #1,(a4)
  1800.     bsr    RemoveSector
  1801.     move.l    NextInList(a3),d0
  1802.     move.l    UnusedSectors(pc),NextInList(a3)
  1803.     move.l    a3,UnusedSectors
  1804.     move.l    d0,a3
  1805.     bra.s    FreeNextSec
  1806.  
  1807. SkipSector
  1808.     move.l    NextInList(a3),a3
  1809.     bra.s    FreeNextSec
  1810.  
  1811. EndDelSectors
  1812.     jsr    Permit(a6)
  1813.     movem.l    (a7)+,a3/a4/a6
  1814.     rts
  1815.  
  1816.  
  1817. ******************    Grabs the next free sector, or deallocates the first 
  1818. * AllocateSector *    one. Then fills in some info. a4 = IOrequest
  1819. ******************    returns d0=sector structure (0=error)
  1820. AllocateSector
  1821.     move.l    UnusedSectors(pc),d0
  1822.     beq.s    DeAllocSector
  1823.     move.l    d0,a3
  1824.     move.l    NextInList(a3),UnusedSectors
  1825.  
  1826. FillStrucInfo
  1827.     move.l    IO_OFFSET(a4),d0
  1828.     move.l    d0,SectorOffset(a3)
  1829.     move.w    d2,WhichDrive(a3)
  1830.  
  1831.     lsr.l    #7,d0
  1832.     and.l    #$1fc,d0
  1833.     lea    SectorHeaders(pc),a2
  1834.     add.w    d0,a2
  1835.     lea    NumBuffers(pc),a0
  1836.     addq.l    #1,0(a0,d2.w)
  1837.     move.l    a3,d0
  1838. NoSectors
  1839.     rts
  1840.  
  1841. DeAllocSector
  1842.     move.l    LastSector(pc),d0
  1843.     beq.s    NoSectors
  1844.     move.l    d0,a3
  1845.     bsr    RemoveSector
  1846.     move.w    WhichDrive(a3),d0
  1847.     lea    NumBuffers(pc),a0
  1848.     subq.l    #1,0(a0,d0.w)
  1849.     bra.s    FillStrucInfo
  1850.  
  1851.  
  1852. ****************** Saves sector being read in
  1853. * SaveReadSector *
  1854. ******************
  1855. SaveReadSector
  1856.     movem.l    a3/a4/a6,-(sp)
  1857.     move.l    a1,a4
  1858.     bsr.s    AllocateSector
  1859.     tst.l    d0
  1860.     beq.s    NoRdStrucs
  1861.  
  1862. WaitRdSector
  1863.     move.l    a4,a1
  1864.     move.l    $4.w,a6
  1865.     jsr    CheckIO(a6)
  1866.     tst.l    d0
  1867.     bne.s    RdDone
  1868.     move.l    GfxBase,a6
  1869.     jsr    WaitTOF(a6)
  1870.     bra.s    WaitRdSector
  1871.  
  1872. RdDone
  1873.     jsr    Forbid(a6)
  1874.  
  1875.     bsr    Add1stSector
  1876.     move.l    IO_DATA(a4),a0
  1877.     lea    Sector(a3),a1
  1878.     bsr    CopySector
  1879.  
  1880. NoRdStrucs
  1881.     move.l    $4.w,a6
  1882.     jsr    Permit(a6)
  1883.     movem.l    (sp)+,a3/a4/a6
  1884.     rts
  1885.  
  1886.  
  1887. SetColour0
  1888.     moveq    #0,d0
  1889. SetCol    move.l    RastPort(pc),a1
  1890.     move.l    GfxBase,a6
  1891.     jmp    SetAPen(a6)
  1892. SetColour1
  1893.     moveq    #1,d0
  1894.     bra.s    SetCol
  1895. SetColour2
  1896.     moveq    #2,d0
  1897.     bra.s    SetCol
  1898. SetColour3
  1899.     moveq    #3,d0
  1900.     bra.s    SetCol
  1901.  
  1902. **************    divides d1/d0, result in d0, remainder in d1
  1903. * LongDivide *
  1904. **************    uses shift & subtract method
  1905. LongDivide
  1906.     movem.l    d2/d3/d4,-(sp)
  1907.     move.l    d0,d4
  1908.     eor.l    d1,d4        d4 is sign of result
  1909.  
  1910.     move.l    d0,d2        make both parameters positive
  1911.     beq.s    DivideBy0
  1912.     bpl.s    div0p
  1913.     neg.l    d2
  1914. div0p    tst.l    d1
  1915.     bpl.s    div1p
  1916.     neg.l    d1
  1917. div1p
  1918.  
  1919.     moveq    #$1f,d3        transfer divsor to top bit positions
  1920. ToEnd    add.l    d2,d2
  1921.     dbcs    d3,ToEnd
  1922.     roxr.l    #1,d2
  1923.  
  1924.     neg.w    d3
  1925.     add.w    #$1f,d3        d3 = number of times to shift
  1926.     moveq    #0,d0
  1927. nextbit    add.l    d0,d0
  1928.     cmp.l    d2,d1
  1929.     bcs.s    nosub
  1930.     addq.w    #1,d0
  1931.     sub.l    d2,d1
  1932. nosub    lsr.l    #1,d2
  1933.     dbra    d3,nextbit
  1934.     tst.l    d4
  1935.     bpl.s    divpos
  1936.     neg.l    d0
  1937. divpos    movem.l    (sp)+,d2/d3/d4
  1938.     rts
  1939. DivideBy0
  1940.     moveq    #-1,d0        prevent divide by 0 crashing
  1941.     bra.s    divpos
  1942.  
  1943. ************    calculates d0 = d0 * d1 for long integers
  1944. * LongMult *
  1945. ************
  1946. LongMult
  1947.     movem.l    d1/d2/d3,-(a7)
  1948.     move.w    d1,d2
  1949.     mulu    d0,d2
  1950.     move.l    d1,d3
  1951.     swap    d3
  1952.     mulu    d0,d3
  1953.     swap    d3
  1954.     clr.w    d3
  1955.     add.l    d3,d2
  1956.     swap    d0
  1957.     mulu    d1,d0
  1958.     swap    d0
  1959.     clr.w    d0
  1960.     add.l    d2,d0
  1961.     movem.l    (a7)+,d1/d2/d3
  1962.     rts
  1963.  
  1964.  
  1965. IntBase        dc.l    0
  1966. GfxBase        dc.l    0
  1967. DosBase        dc.l    0
  1968. TrackBase    dc.l    0
  1969.  
  1970. StartSP        dc.l    0
  1971.  
  1972. FontAttr    dc.l    FontName    font structure for topaz 8
  1973.         dc.w    8,0
  1974. TopazFont    dc.l    0
  1975.  
  1976. FewerButton    dc.l    0        Next gadget
  1977.         dc.w    $a,$57,$54,$d    GadX,GadY, widths
  1978. FewerGadgFlags    dc.w    0        Flags
  1979.         dc.w    3
  1980.         dc.w    1
  1981.         dc.l    0,0,0,0,0
  1982.         dc.w    FewerGadget
  1983.         dc.l    0
  1984.  
  1985. MoreButton    dc.l    FewerButton    Next gadget
  1986.         dc.w    $15b,$57,$43,$d    GadX,GadY, widths
  1987. MoreGadgFlags    dc.w    0        Flags
  1988.         dc.w    3        Activation
  1989.         dc.w    1        Type
  1990.         dc.l    0,0        Renders
  1991.         dc.l    0,0,0        Intuitext,Mutual Exclude,Special Info
  1992.         dc.w    MoreGadget    Gadget ID
  1993.         dc.l    0        
  1994.  
  1995. MyWindow
  1996.     dc.w    220,0                leftedge,TopEdge
  1997.     dc.w    WindowSmallX,WindowSmallY    Width,height
  1998.     dc.b    0,1                Pens
  1999.     dc.l    CLOSEWINDOW+GADGETUP+GADGETDOWN+MENUPICK IDCMP flags
  2000.     dc.l    WINDOWDRAG+WINDOWDEPTH+WINDOWCLOSE+NOCAREREFRESH
  2001.     dc.l    MoreButton            1st Gadget
  2002.     dc.l    0                checkmark
  2003.     dc.l    0                title (filled in later)
  2004.     dc.l    0,0                current screen,bitmap
  2005.     dc.w    0,0,WindowBigX,WindowBigY    Min sizes,Max sizes
  2006.     dc.w    1                Workbenchscreen
  2007.  
  2008. Window        dc.l    0
  2009. MorePressed    dc.b    0
  2010. FewerPressed    dc.b    0
  2011. Signals        dc.l    0    Signals used by program to wait for
  2012.  
  2013. RastPort    dc.l    0
  2014.  
  2015. ForcePrint    dc.b    0
  2016. GadgetSmall    dc.b    -1
  2017.  
  2018. TrackdiskIOreq
  2019. TimerIOreq    ds.b    IOSTD_SIZE
  2020. TrackdiskPort
  2021. TimerPort    ds.b    MP_SIZE
  2022. TimerPortOk    dc.l    0
  2023.  
  2024. ProgramPort    ds.b    MP_SIZE
  2025.  
  2026. Date        ds.b    ds_SIZEOF
  2027.  
  2028. DevUnits    dc.l    0,0,0,0
  2029.  
  2030. SectorHeaders    ds.l    $80
  2031.  
  2032. FirstSector    dc.l    0    1st & last sectors for allocation/deallocation
  2033. LastSector    dc.l    0
  2034.  
  2035. UnusedSectors    dc.l    0
  2036.  
  2037. TotalReads    dc.l    0
  2038. LastTotalReads    dc.l    -1
  2039. TotalWrites    dc.l    0
  2040. LastTotalWrites    dc.l    -1
  2041. TotalRHits    dc.l    0
  2042. LastTotalRHits    dc.l    -1
  2043.  
  2044. NumBlocks    dc.l    0        Number of allocated blocks
  2045. LastNumBlocks    dc.l    -1        last number of blocks
  2046.  
  2047. NumReads    dc.l    0,0,0,0        Number of reads for drives
  2048.         dc.l    -1,-1,-1,-1    last number of reads
  2049. NumWrites    dc.l    0,0,0,0
  2050.         dc.l    -1,-1,-1,-1
  2051. NumReadHits    dc.l    0,0,0,0
  2052.         dc.l    -1,-1,-1,-1
  2053. NumBuffers    dc.l    0,0,0,0
  2054.         dc.l    -1,-1,-1,-1
  2055.  
  2056.